/* 
 * File:   XshareMem.cpp
 * Author: minaev
 * 
 * Created on 31 Октябрь 2013 г., 8:56
 */

#include "XshareMem.h"
#include "Xservice.h"

#include <stddef.h>
#include <stdio.h>
#include <string.h>

XshareMem::XshareMem() {
    shareLines = NULL;
    countline = 0;
    
    /*
    countline = SLN_COUNT;
    lensBlockLine[SLN_XADRS] = 4;
    lensBlockLine[SLN_XSTAT] = 1;
    lensBlockLine[SLN_XREQSTAT] = 1;
    lensBlockLine[SLN_XADC] = 2;
    lensBlockLine[SLN_XFIXADC] = 2;
    shareLines = new XshareLine*[countline];
    for (int i = 0; i < countline; i++) {
        shareLines[i] = new XshareLine(lensBlockLine[i], 0);
    }*/
}

XshareMem::~XshareMem() {
    for (uint16_t i = 0; i < countline; i++) {
        delete this->shareLines[i];
    }
    delete [] this->shareLines;
}

XshareLine* XshareMem::getLine(uint16_t indx) {
    if (indx<this->countline) {
        return this->shareLines[indx];
    }
    return NULL;
}

uint16_t XshareMem::getLineLength(uint16_t indx) {
    if (indx<this->countline) {
        return this->shareLines[indx]->getLength();
    }
    return 0;
}

uint8_t XshareMem::getLineBlockLength(uint16_t indx) {
    if (indx<this->countline) {
        return this->shareLines[indx]->getBlockLen();
    }
    return 0;
}

uint32_t XshareMem::getLineBytesLength(uint16_t indx) {
    if (indx<this->countline) {
        return this->shareLines[indx]->getBytesLength();
    }
    return 0;
}

/**
 *  Find block into shared line
 * @param findBlock - finding block
 * @param numBlock - number line for find
 * @return position found block in line, or -1 if not found
 */
int XshareMem::findInLine(void* findBlock, uint16_t numLine) {
    if (numLine<this->countline) {
        return this->shareLines[numLine]->findBlock(findBlock);
    }
    return -1;
}

void* XshareMem::read(uint16_t numLine, uint16_t numBlock) {
    if (numLine < countline) {
        if (numBlock<this->shareLines[numLine]->getLength()) {
            return this->shareLines[numLine]->read(numBlock);
        }
    }
    return NULL;
}

/**
 * Write to ShareMem
 * @param writeBuf - data
 * @param numLine - number of share line
 * @param numBlock - number of block
 * @param countBlocks - count write block
 * @return 0 - success, else error
 */
int XshareMem::write(void* writeBuf, uint16_t numLine,
        uint16_t numBlock, uint16_t countBlocks) {
//    printf("write numLine: %i, numBlock %i, countBlock %i\n",numLine,numBlock,countBlocks);
    if (numLine < countline) {
        if (numBlock<this->shareLines[numLine]->getLength()) {
            this->shareLines[numLine]->write(writeBuf, countBlocks, numBlock);
            return 0;
        } else {
            Xmsg::printf("write SHAREMEM error\n");
            return 1;
        }
    } else {
        Xmsg::printf("write SHAREMEM error2\n");
        return 2;
    }
}

void XshareMem::write(void* writeBuf, uint16_t numLine, uint16_t numBlock) {
    if (numLine < countline) {
        if (numBlock<this->shareLines[numLine]->getLength()) {
//            Xmsg::printf("SHRWRT: 0x%x\n",*(uint8_t*)writeBuf);
            this->shareLines[numLine]->write(writeBuf, 1, numBlock);
        }
        else{
                Xmsg::printf("XshareMem write error. Bad Length\n");
        }
    }else{
        Xmsg::printf("XshareMem write error. Bad numLine\n");
    }
}

int XshareMem::addLineBlock(const void* block, uint16_t numLine) {
    if (numLine < countline) {
        return this->shareLines[numLine]->addBlock(block);
    }else{
        return -1;
    }
}

int XshareMem::addLineBlockWithoutRepeate(const void* block,uint16_t numLine){
    if (numLine < countline) {
        return this->shareLines[numLine]->addBlockWithoutRepeate(block);
    }else{
        return -1;
    }
}

int XshareMem::removeLineBlock(uint16_t nblock,uint16_t numLine){
    if (numLine < countline) {
        return this->shareLines[numLine]->removeBlock(nblock);
    }else{
        return -1;
    }
}

int XshareMem::removeLineBlock(void* block,uint16_t numLine){
    if (numLine < countline) {
        return this->shareLines[numLine]->removeBlock(block);
    }else{
        return -1;
    }
}    

void XshareMem::addLine(uint8_t lenBlock){
    static XshareLine** bufLines;
    bufLines = shareLines;
    this->shareLines = new XshareLine*[countline+1];
    if(bufLines!=NULL){
        memcpy(this->shareLines,bufLines,countline*sizeof(XshareLine*));
    }
    this->shareLines[countline] = new XshareLine(lenBlock,0);
    countline++;
}

uint16_t XshareMem::getCountLines() {
    return this->countline;
}

void XshareMem::printMem() {
    for (uint16_t i = 0; i < countline; i++) {
        Xmsg::printf("ln:%i|blen:%i|", i, this->getLineBlockLength(i));
        Xservice::printArrayToHexStr(this->getLine(i)->toBytes(), this->getLineBytesLength(i));
    }
}
